/* pecanpico2 copyright (C) 2013  KT5TK
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef __RADIO_SI446X_H__
#define __RADIO_SI446X_H__
#include "radio.h"
#define RADIO_DRIVER_EXTENDED_SUPPORT

 
#define myCopterRX
// PIN Definitions:
#ifdef myCopterRC
#define RADIO_SDN_PIN   8
#define NIRQpin  28
#endif
#ifdef myCopterRX
#define RADIO_SDN_PIN   30
#define NIRQpin  38
#endif

#define SSpin   31    // SS
#define SCKpin  32  // SCK
#define MOSIpin 34   // MOSI
#define MISOpin 33   // MISO
 
 
#define radio_hal_ClearNsel()         digitalWrite(SSpin,LOW);    
#define radio_hal_SetNsel()           digitalWrite(SSpin,HIGH);    
#define radio_hal_AssertShutdown()    digitalWrite(RADIO_SDN_PIN, HIGH);  
#define radio_hal_DeassertShutdown()  digitalWrite(RADIO_SDN_PIN, LOW); 
#define radio_hal_NirqLevel()          digitalRead(NIRQpin)




//-----------------------------------------------------------
extern u8 ctsWentHigh;
extern u8 Pro2Cmd[16];
extern union si446x_cmd_reply_union Si446xCmd;
//----------------------------------------------------------
enum
{
    SI446X_SUCCESS,
    SI446X_NO_PATCH,
    SI446X_CTS_TIMEOUT,
    SI446X_PATCH_FAIL,
    SI446X_COMMAND_ERROR
};
#define SI466X_FIFO_SIZE 64
//============================radio.c============================================
/*! Maximal packet length definition (FIFO size) */
#define RADIO_MAX_PACKET_LENGTH     64u

/*****************************************************************************
 *  Global Typedefs & Enums
 *****************************************************************************/
typedef struct
{
    unsigned char  *Radio_ConfigurationArray;//modify by lisong. U8->unsigned char

    unsigned char   Radio_ChannelNumber;
    unsigned char   Radio_PacketLength;
    unsigned char   Radio_State_After_Power_Up;

    unsigned short  Radio_Delay_Cnt_After_Reset;
   unsigned char   Radio_CustomPayload[RADIO_MAX_PACKET_LENGTH];
} tRadioConfiguration;
/*****************************************************************************
 *  Global Variable Declarations
 *****************************************************************************/

extern U8 Radio_Configuration_Data_Array[];
extern const tRadioConfiguration RadioConfiguration;
extern const tRadioConfiguration *pRadioConfiguration;
extern U8 variableRadioPacket[RADIO_MAX_PACKET_LENGTH];
extern U8 fixRadioPacket[RADIO_MAX_PACKET_LENGTH];
//=========================================================
class RadioSi446x : public Radio {
  public:
    virtual void setup();
    virtual void ptt_on();
    virtual void ptt_off();
    virtual void set_freq(unsigned long freq);
    virtual int get_powerlevel();
    virtual void SetGPIO1(int val);
    //-------------chwh 2013.12.10 add------------------------------------
    void vRadio_PowerUp(void);
    void  vRadio_Init(void);
    void SetField1Lenth(u16 len,u8 cfg,u8 crc);
    void SetField2Lenth(u16 len,u8 cfg,u8 crc);
    void SetField3Lenth(u16 len,u8 cfg,u8 crc);
    void SetField4Lenth(u16 len,u8 cfg,u8 crc);
    void SetField5Lenth(u16 len,u8 cfg,u8 crc);

    void  vRadio_StartRX_Variable_Packet(U8);
    U8    bRadio_Check_Tx_RX(void);
    void  vRadio_StartTx_Variable_Packet(U8, U8*, U8);

    void  vRadio_StartTx_Fixed_Packet(U8, U8 *);
    void  vRadio_StartRX_Fixed_Packet(U8);
    u8   vRadio_CheckReceived_Fixed_Packet(void);
    void si446x_part_info(void);
    void si446x_set_property( U8 GROUP, U8 NUM_PROPS, U8 START_PROP, ... );
  private:
    void SendCmdReceiveAnswer(int byteCountTx, int byteCountRx, const char* pData);
    void reset(void);
    void setModem(void);
    void start_tx(void);
    void stop_tx(void);
    void tune_tx(void);
    void setFrequency(unsigned long freq); 
    //------------------------------
//------------------chwh add ----------------------------
    u8 radio_comm_GetResp(u8 byteCount, u8* pData);
    u8 radio_comm_PollCTS(void);
    void radio_comm_SendCmd(u8 byteCount, u8* pData);
    u8 radio_comm_SendCmdGetResp(u8 cmdByteCount, u8* pCmdData, u8 respByteCount, u8* pRespData);
    void radio_comm_ReadData(u8 cmd, u8 pollCts, u8 byteCount, u8* pData);
    void radio_comm_WriteData(u8 cmd, u8 pollCts, u8 byteCount, u8* pData);
     
    
   void si446x_reset(void);
   void si446x_power_up(U8 BOOT_OPTIONS, U8 XTAL_OPTIONS, U32 XO_FREQ);

    U8 si446x_configuration_init(const U8* pSetPropCmd);
    U8 si446x_apply_patch(void);
    

   void si446x_start_tx(U8 CHANNEL, U8 CONDITION, U16 TX_LEN);
   void si446x_start_rx(U8 CHANNEL, U8 CONDITION, U16 RX_LEN, U8 NEXT_STATE1, U8 NEXT_STATE2, U8 NEXT_STATE3);

   void si446x_get_int_status(U8 PH_CLR_PEND, U8 MODEM_CLR_PEND, U8 CHIP_CLR_PEND);
   void si446x_gpio_pin_cfg(U8 GPIO0, U8 GPIO1, U8 GPIO2, U8 GPIO3, U8 NIRQ, U8 SDO, U8 GEN_CONFIG);

   
   void si446x_change_state(U8 NEXT_STATE1);
#ifdef RADIO_DRIVER_EXTENDED_SUPPORT
/* Extended driver support functions */
  void si446x_nop(void);

  void si446x_fifo_info(U8 FIFO);
  void si446x_write_tx_fifo( U8 numBytes, U8* pData );
  void si446x_read_rx_fifo( U8 numBytes, U8* pRxData );

  void si446x_get_property(U8 GROUP, U8 NUM_PROPS, U8 START_PROP);
#ifdef RADIO_DRIVER_FULL_SUPPORT
    /* Full driver support functions */
    void si446x_func_info(void);

    void si446x_frr_a_read(U8 respByteCount);
    void si446x_frr_b_read(U8 respByteCount);
    void si446x_frr_c_read(U8 respByteCount);
    void si446x_frr_d_read(U8 respByteCount);

    void si446x_get_adc_reading(U8 ADC_EN);
    void si446x_get_packet_info(U8 FIELD_NUMBER_MASK, U16 LEN, S16 DIFF_LEN );
    void si446x_get_ph_status(U8 PH_CLR_PEND);
    void si446x_get_modem_status( U8 MODEM_CLR_PEND );
    void si446x_get_chip_status( U8 CHIP_CLR_PEND );

    void si446x_ircal(U8 SEARCHING_STEP_SIZE, U8 SEARCHING_RSSI_AVG, U8 RX_CHAIN_SETTING1, U8 RX_CHAIN_SETTING2);
    void si446x_protocol_cfg(U8 PROTOCOL);

    void si446x_request_device_state(void);

    void si446x_rx_hop(U8 INTE, U8 FRAC2, U8 FRAC1, U8 FRAC0, U8 VCO_CNT1, U8 VCO_CNT0);
    void si446x_agc_override(U8 AGC_OVERRIDE);
  #endif
#endif
 

 
    
};

#endif
